package com.supply.service.impl;

import com.supply.global.Constants;
import com.supply.mapper.SalesBillMapper;
import com.supply.pojo.*;
import com.supply.service.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class TaskProcessServiceImpl implements TaskProcessService {
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private ManagementService managementService;

    @Autowired
    private LeaveBillService leaveBillService;
    @Autowired
    private OutBoundBillService outBoundBillService;
    @Autowired
    private ProcurementBillService procurementBillService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private SalesBillMapper salesBillMapper;

    @Override
    public List<Task> queryByUserId(Long id) {
        return taskService.createTaskQuery().taskAssignee(id.toString()).list();
    }

    @Override
    public List<Comment> queryAllCommentByTaskId(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        List<Comment> comments = taskService.getProcessInstanceComments(task.getProcessInstanceId());
        return comments;
    }

    @Override
    public List<String> queryButtonListByTaskId(String taskId) {
        // 返回存放连线的名称集合
        List<String> list = new ArrayList<>();
        // 1:使用任务ID，查询任务对象
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        // 2：获取流程定义ID
        String processDefinitionId = task.getProcessDefinitionId();
        // 3：查询ProcessDefinitionEntiy对象
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService
                .getProcessDefinition(processDefinitionId);
        // 使用任务对象Task获取流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        // 使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
        ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
                .processInstanceId(processInstanceId)// 使用流程实例ID查询
                .singleResult();
        // 获取当前活动的id
        String activityId = pi.getActivityId();
        // 4：获取当前的活动
        ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);
        // 5：获取当前活动完成之后连线的名称
        List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();
        if (pvmList != null && pvmList.size() > 0) {
            for (PvmTransition pvm : pvmList) {
                //获取连线的名称
                String name = (String) pvm.getProperty("name");
                if (StringUtils.isNotBlank(name)) {
                    list.add(name);
                } else {
                    list.add("默认提交");
                }
            }
        }
        return list;
    }

    @Override
    public String getBusinessKeyByTaskId(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();
        return processInstance.getBusinessKey();
    }

    @Override
    public void complete(TaskCompleteData taskCompleteData) {
        //获取任务对象
        Task task = taskService.createTaskQuery().taskId(taskCompleteData.getTaskId()).singleResult();
        //设置批注人Id,并提交批注
        Authentication.setAuthenticatedUserId(taskCompleteData.getUserId().toString());
        //添加批注信息
        taskService.addComment(taskCompleteData.getTaskId(), task.getProcessInstanceId(), taskCompleteData.getComment());
        //获取唯一标识businessKey
        String businessKey = getBusinessKeyByTaskId(taskCompleteData.getTaskId());

        //设置流程推进信息，并推进流程
        Map<String, Object> map = new HashMap<>();
        map.put("msg", taskCompleteData.getButtonValue());
        taskService.complete(taskCompleteData.getTaskId(), map);

        //判断流程是否结束，若结束则将对应表单对象设置为通过审核
        ProcessInstance pi = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();
        //流程实例为空则代表流程结束，修改相应申请单状态
        if (pi == null) {
            String applyType = businessKey.split("\\.")[0];
            Long id = Long.parseLong(businessKey.split("\\.")[1]);

            if (applyType.equals(Constants.LEAVE_KEY)) {
                LeaveBill leaveBill = leaveBillService.queryById(id);
                leaveBill.setState(1);
                leaveBillService.saveOrUpdate(leaveBill);
            } else if (applyType.equals(Constants.PROCUREMENT_KEY)) {
                ProcurementBill procurementBill = procurementBillService.queryById(id);
                procurementBill.setState(1);
                int rs = procurementBillService.saveOrUpdate(procurementBill);

                //采购单审核成功，成功采购商品，更新商品库存信息
                if (rs >= 1) {
                    Goods goods = goodsService.queryById(procurementBill.getGoodsId());
                    goods.setQuantity(goods.getQuantity() + procurementBill.getQuantity());
                    goodsService.saveOrUpdate(goods);
                }
            } else if (applyType.equals(Constants.OUTBOUND_KEY)) {
                OutBoundBill outBoundBill = outBoundBillService.queryById(id);
                outBoundBill.setState(1);
                int rs = outBoundBillService.saveOrUpdate(outBoundBill);

                //出库单审核成功，若出库单关联有销售单，则修改销售单状态为成功出库
                if (outBoundBill.getSalesBillId() != null) {
                    SalesBill salesBill = salesBillMapper.selectByPrimaryKey(outBoundBill.getSalesBillId());
                    salesBill.setState(2);
                    salesBillMapper.updateByPrimaryKey(salesBill);
                }
            }
        }
    }

    @Override
    public List<Comment> getCurrentCommentsByBusinessKey(String businessKey) {
        Task task = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).singleResult();
        List<Comment> comments = taskService.getProcessInstanceComments(task.getProcessInstanceId());
        return comments;
    }

    @Override
    public List<Comment> getOverCommentsByBusinessKey(String businessKey) {
        //通过历史表查询历史流程实例
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceBusinessKey(businessKey)
                .singleResult();
        //通过历史流程实例ID获取批注信息
        List<Comment> comments = taskService.getProcessInstanceComments(historicProcessInstance.getId());
        return comments;
    }

    @Override
    public int deleteByTaskId(String taskId) {
        //获取任务对象
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //获取流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();
        //获取唯一标识businessKey
        String businessKey = processInstance.getBusinessKey();
        String applyType = businessKey.split("\\.")[0];
        Long id = Long.parseLong(businessKey.split("\\.")[1]);

        //删除流程实例，先删除runtime，再删除history，顺序不能错
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(), "");
        historyService.deleteHistoricProcessInstance(task.getProcessInstanceId());

        //处理被删除流程的相应申请单信息，将状态设置为审核不通过
        if (applyType.equals(Constants.LEAVE_KEY)) {
            LeaveBill leaveBill = leaveBillService.queryById(id);
            leaveBill.setState(2);
            return leaveBillService.saveOrUpdate(leaveBill);
        } else if (applyType.equals(Constants.OUTBOUND_KEY)) {
            OutBoundBill outBoundBill = outBoundBillService.queryById(id);
            outBoundBill.setState(2);

            //出库单审核不通过，商品回退，库存数量复原，更新库存
            Goods goods = goodsService.queryById(outBoundBill.getGoodsId());
            goods.setQuantity(goods.getQuantity() + outBoundBill.getQuantity());
            goodsService.saveOrUpdate(goods);

            //若出库单关联有销售单，则将销售单复原，设置为等待物料员处理出库
            if (outBoundBill.getSalesBillId() != null) {
                SalesBill salesBill = salesBillMapper.selectByPrimaryKey(outBoundBill.getSalesBillId());
                salesBill.setState(0);
                salesBillMapper.updateByPrimaryKey(salesBill);
            }

            return outBoundBillService.saveOrUpdate(outBoundBill);
        } else if (applyType.equals(Constants.PROCUREMENT_KEY)) {
            ProcurementBill procurementBill = procurementBillService.queryById(id);
            procurementBill.setState(2);
            return procurementBillService.saveOrUpdate(procurementBill);
        }

        return 0;
    }

    @Override
    public String getCurrentProgress(String businessKey) {
        //获取任务对象
        Task task = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).singleResult();
//        String assignee = task.getAssignee();
        if (task == null) {
            return null;
        } else {
            return task.getName();
        }
    }
}
